Цепь.отд
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы
 
 glagol.png Программируем по-русски
 

Основная задача Глагола — дать человеку возможность воплощать свои мысли на языке, близком к его родному языку.

Издатель Глагола
 

 
(*~\Глагол\Отделы\Иное~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                        ОТДЕЛ Цепь;
(*============================================================================*
 * НАЗНАЧЕНИЕ: обработка цепочек знаков (РЯД ИЗ ЗНАК или РЯД ИЗ ЦЕПЬ)         * 
 * ПРИМЕЧАНИЯ:                                                                * 
 *    Цепочки обычно заканчиваются знаком "0X". Их длина не может быть        * 
 *    больше МАКС(ЦЕЛ). Если выходная цепочка не помещается в ряд,            * 
 *    предназначенный для ответа, то она укорачивается до длины этого ряда.   * 
 *============================================================================*)
ИСПОЛЬЗУЕТ
  Буква,
  Знак;
ВИД
  Доступ-=ДОСТУП К ЦЕПЬ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Сравнить-(ц1-,ц2-:ЦЕПЬ):ЦЕЛ;
(* Возвращает результат алфавитного сравнения цепочек <ц1> и <ц2>. *)
ПЕР
  р1,р2,минр,поз,отв:ЦЕЛ;
УКАЗ
  р1:=РАЗМЕР(ц1);
  р2:=РАЗМЕР(ц2);
  ЕСЛИ р1 < р2 ТО минр:=р1 ИНАЧЕ минр:=р2 КОН;
  поз:=0;
  КОЛЬЦО
    отв:=ВЦЕЛ(ц1[поз])-ВЦЕЛ(ц2[поз]);
    ЕСЛИ (отв # 0) ИЛИ (ц1[поз] = 0X) ТО ВОЗВРАТ отв КОН;
    УВЕЛИЧИТЬ(поз);
    ЕСЛИ поз = минр ТО ВОЗВРАТ р1-р2 КОН
  КОН;
  ВОЗВРАТ 0
КОН Сравнить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПозицияЗнака-(зн:ЗНАК; цепь-:ЦЕПЬ; поз:ЦЕЛ):ЦЕЛ;
(* Возвращает позицию первого знака <зн> в цепочке <цепь>. Поиск начинается
 * с позиции <поз>. Если <зн> нет в <цепь>, то возвращает -1. *)
ПЕР
  дл:ЦЕЛ;
УКАЗ
  дл:=ДЛИНА(цепь);
  ЕСЛИ поз < 0 ТО
    поз:=0
  КОН;
  ПОКА (поз < дл) И (цепь[поз] # зн) ВЫП
    УВЕЛИЧИТЬ(поз)
  КОН;
  ЕСЛИ поз >= дл ТО
    поз:=-1
  КОН;
  ВОЗВРАТ поз
КОН ПозицияЗнака;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Позиция-(обр-,цепь-:ЦЕПЬ; поз:ЦЕЛ):ЦЕЛ;
(* Возвращает позицию первого включения образца <обр> в цепочке <цепь>. Поиск
 * начинается с позиции <поз>. Если <обр> нет в <цепь>, то возвращает -1. *)
ПЕР
  дл,обрп,обрдл:ЦЕЛ;
УКАЗ
  ЕСЛИ поз < 0 ТО
    поз:=0
  КОН;
  дл:=ДЛИНА(цепь);
  обрдл:=ДЛИНА(обр);
  обрп:=0;
  ПОКА (обрп < обрдл) И (поз+обрп < дл) ВЫП
    ЕСЛИ цепь[поз+обрп] = обр[обрп] ТО
      УВЕЛИЧИТЬ(обрп)
    ИНАЧЕ
      обрп:=0;
      УВЕЛИЧИТЬ(поз)
    КОН
  КОН;
  ЕСЛИ обрп # обрдл ТО
    поз:=-1
  КОН;
  ВОЗВРАТ поз
КОН Позиция;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Начало-(обр-,цепь-:ЦЕПЬ):КЛЮЧ;
(* Возвращает ВКЛ если образец <обр> является началом цепочки <цепь>. *)
ПЕР
  дл,поз,обрдл:ЦЕЛ;
УКАЗ
  дл:=ДЛИНА(цепь);
  обрдл:=ДЛИНА(обр);
  ЕСЛИ дл < обрдл ТО
    ВОЗВРАТ ОТКЛ
  КОН;
  поз:=0;
  ПОКА поз < обрдл ВЫП
    ЕСЛИ цепь[поз] = обр[поз] ТО
      УВЕЛИЧИТЬ(поз)
    ИНАЧЕ
      ВОЗВРАТ ОТКЛ
    КОН
  КОН;
  ВОЗВРАТ ВКЛ
КОН Начало;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ПохожееНачало-(обр-,цепь-:ЦЕПЬ):КЛЮЧ;
(* Возвращает ВКЛ если образец <обр> похож на начало цепочки <цепь>
 * (сравнение идёт без учёта заглавных и строчных букв). *)
ПЕР
  дл,поз,обрдл:ЦЕЛ;
УКАЗ
  дл:=ДЛИНА(цепь);
  обрдл:=ДЛИНА(обр);
  ЕСЛИ дл < обрдл ТО
    ВОЗВРАТ ОТКЛ
  КОН;
  поз:=0;
  ПОКА поз < обрдл ВЫП
    ЕСЛИ Буква.ВСтрочную(цепь[поз]) = Буква.ВСтрочную(обр[поз]) ТО
      УВЕЛИЧИТЬ(поз)
    ИНАЧЕ
      ВОЗВРАТ ОТКЛ
    КОН
  КОН;
  ВОЗВРАТ ВКЛ
КОН ПохожееНачало;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Часть-(откуда-,куда+:ЦЕПЬ; откудап,дл:ЦЕЛ);
(* Переписывает часть цепочки <откуда>, начиная с позиции <откудап>, и
 * длиной <дл> знаков в цепочку <куда>. *)
  ПЕР
  кудап,максдл:ЦЕЛ;
УКАЗ
  ЕСЛИ откудап < 0 ТО
    дл:=0
  КОН;
  максдл:=ДЛИНА(откуда)-откудап;
  ЕСЛИ дл > максдл ТО
    дл:=максдл
  КОН;
  максдл:=РАЗМЕР(куда)-1;
  ЕСЛИ дл > максдл ТО
    дл:=максдл
  КОН;
  кудап:=0;
  ПОКА кудап < дл ВЫП
    куда[кудап]:=откуда[откудап];
    УВЕЛИЧИТЬ(кудап); УВЕЛИЧИТЬ(откудап)
  КОН;
  куда[кудап]:=0X
КОН Часть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Добавить-(куда+,откуда-:ЦЕПЬ);
(* Добавляет в конец цепочки <куда> цепочку <откуда>. *)
ПЕР
  кудап,откудап,откудар,кудар:ЦЕЛ;
УКАЗ
  кудап:=ДЛИНА(куда);
  откудап:=0;
  кудар:=РАЗМЕР(куда)-1;
  откудар:=РАЗМЕР(откуда);
  ПОКА (кудап < кудар) И (откудап < откудар) И (откуда[откудап] # 0X) ВЫП
    куда[кудап]:=откуда[откудап];
    УВЕЛИЧИТЬ(кудап); 
    УВЕЛИЧИТЬ(откудап)
  КОН;
  куда[кудап]:=0X
КОН Добавить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьЗнак-(куда+:ЦЕПЬ; зн:ЗНАК);
(* Добавляет в конец цепочки <куда> знак <зн>. *)
ПЕР
  кудадл:ЦЕЛ;
УКАЗ
  кудадл:=ДЛИНА(куда);
  ЕСЛИ кудадл+1 < РАЗМЕР(куда) ТО
    куда[кудадл]:=зн;
    куда[кудадл+1]:=0X
  КОН
КОН ДобавитьЗнак;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьЧасть-(откуда-,куда+:ЦЕПЬ; откудап,дл:ЦЕЛ);
(* Переписывает часть цепочки <откуда>, начиная с позиции <откудап>, и
 * длиной <дл> знаков в конец цепочки <куда>. *)
ПЕР
  кудап,максдл:ЦЕЛ;
УКАЗ
  кудап:=ДЛИНА(куда);
  ЕСЛИ откудап < 0 ТО
    дл:=0
  КОН;
  максдл:=ДЛИНА(откуда)-откудап;
  ЕСЛИ дл > максдл ТО
    дл:=максдл
  КОН;
  максдл:=РАЗМЕР(куда)-1-кудап;
  ЕСЛИ дл > максдл ТО
    дл:=максдл
  КОН;
  УВЕЛИЧИТЬ(дл,кудап);
  ПОКА кудап < дл ВЫП
    куда[кудап]:=откуда[откудап];
    УВЕЛИЧИТЬ(кудап); УВЕЛИЧИТЬ(откудап);
  КОН;
  куда[кудап]:=0X
КОН ДобавитьЧасть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВЗаглавные-(цепь+:ЦЕПЬ);
(* Переводит все буквы цепочки <цепь> в заглавные буквы. *)
ПЕР
  поз:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
  ОТ поз:=0 ДО РАЗМЕР(цепь)-1 ВЫП
    зн:=цепь[поз];
    ЕСЛИ зн = 0X ТО
      ВОЗВРАТ
    КОН;
    цепь[поз]:=Буква.ВЗаглавную(зн)
  КОН
КОН ВЗаглавные;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВСтрочные-(цепь+:ЦЕПЬ);
(* Переводит все буквы цепочки <цепь> в строчные буквы. *)
ПЕР
  поз:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
  ОТ поз:=0 ДО РАЗМЕР(цепь)-1 ВЫП
    зн:=цепь[поз];
    ЕСЛИ зн = 0X ТО
      ВОЗВРАТ
    КОН;
    цепь[поз]:=Буква.ВСтрочную(зн)
  КОН
КОН ВСтрочные;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВДос-(цепь-:ЦЕПЬ; дос+:РЯД ИЗ ЯЧЦЕЛ);
(* Переводит все знаки цепочки <цепь> в Дос знаки ряда <дос>. *)
ПЕР
  знак:ЗНАК;
  поз,р:ЦЕЛ;
УКАЗ
  ЕСЛИ РАЗМЕР(дос) < РАЗМЕР(цепь) ТО
    р:=РАЗМЕР(дос)
  ИНАЧЕ
    р:=РАЗМЕР(цепь)
  КОН;
  ОТ поз:=0 ДО р-1 ВЫП
    знак:=цепь[поз];
    дос[поз]:=Знак.ВДос(знак);
    ЕСЛИ знак = 0X ТО
      ВОЗВРАТ
    КОН
  КОН
КОН ВДос;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВВин-(цепь-:ЦЕПЬ; вин+:РЯД ИЗ ЯЧЦЕЛ);
(* Переводит все знаки цепочки <цепь> в Вин знаки ряда <вин>. *)
ПЕР
  знак:ЗНАК;
  поз,р:ЦЕЛ;
УКАЗ
  ЕСЛИ РАЗМЕР(вин) < РАЗМЕР(цепь) ТО
    р:=РАЗМЕР(вин)
  ИНАЧЕ
    р:=РАЗМЕР(цепь)
  КОН;
  ОТ поз:=0 ДО р-1 ВЫП
    знак:=цепь[поз];
    вин[поз]:=Знак.ВВин(знак);
    ЕСЛИ знак = 0X ТО
      ВОЗВРАТ
    КОН
  КОН
КОН ВВин;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИзВин-(вин-:РЯД ИЗ ЯЧЦЕЛ; цепь+:ЦЕПЬ);
(* Переводит все Вин знаки ряда <вин> в цепочку знаков. *)
ПЕР
  зн:ЯЧЦЕЛ;
  поз,р:ЦЕЛ;
УКАЗ
  ЕСЛИ РАЗМЕР(вин) < РАЗМЕР(цепь) ТО
    р:=РАЗМЕР(вин)
  ИНАЧЕ
    р:=РАЗМЕР(цепь)
  КОН;
  ОТ поз:=0 ДО р-1 ВЫП
    зн:=вин[поз];
    цепь[поз]:=Знак.ИзВин(зн);
    ЕСЛИ зн = 0 ТО
      ВОЗВРАТ
    КОН
  КОН
КОН ИзВин;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ИзДос-(дос-:РЯД ИЗ ЯЧЦЕЛ; цепь+:ЦЕПЬ);
(* Переводит все Дос знаки ряда <дос> в цепочку знаков. *)
ПЕР
  зн:ЯЧЦЕЛ;
  поз,р:ЦЕЛ;
УКАЗ
  ЕСЛИ РАЗМЕР(дос) < РАЗМЕР(цепь) ТО
    р:=РАЗМЕР(дос)
  ИНАЧЕ
    р:=РАЗМЕР(цепь)
  КОН;
  ОТ поз:=0 ДО р-1 ВЫП
    зн:=дос[поз];
    цепь[поз]:=Знак.ИзДос(зн);
    ЕСЛИ зн = 0 ТО
      ВОЗВРАТ
    КОН
  КОН
КОН ИзДос;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Удалить-(откуда+:ЦЕПЬ; удалп,удалдл:ЦЕЛ);
(* Удаляет <удалдл> знаков цепочки <откуда>, начиная с позиции <удалп>. *)
ПЕР
  откудадл:ЦЕЛ;
УКАЗ
  откудадл:=ДЛИНА(откуда);
  ЕСЛИ (удалдл < 1) ИЛИ (удалп < 0) ИЛИ (удалп >= откудадл) ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ удалдл > откудадл-удалп ТО
    удалдл:=откудадл-удалп
  КОН;
  откудадл:=откудадл-удалдл;
  ПОКА удалп < откудадл ВЫП
    откуда[удалп]:=откуда[удалп+удалдл];
    УВЕЛИЧИТЬ(удалп)
  КОН;
  откуда[удалп]:=0X
КОН Удалить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УдалитьКонПробелы-(цепь+:ЦЕПЬ);
(* Удаляет пробелы в конце цепочки <цепь>. *)
ПЕР
  поз:ЦЕЛ;
УКАЗ
  поз:=ДЛИНА(цепь)-1;
  ПОКА (поз >= 0) И (цепь[поз]=" ") ВЫП
    УМЕНЬШИТЬ(поз)
  КОН;
  цепь[поз+1]:=0X
КОН УдалитьКонПробелы;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УдалитьНачПробелы-(цепь+:ЦЕПЬ);
(* Удаляет пробелы в начале цепочки <цепь>. *)
ПЕР
  поз,р:ЦЕЛ;
УКАЗ
  поз:=0;
  р:=РАЗМЕР(цепь);
  ПОКА (поз < р) И (цепь[поз]=" ") ВЫП
    УВЕЛИЧИТЬ(поз)
  КОН;
  Удалить(цепь,0,поз)
КОН УдалитьНачПробелы;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА УдалитьПробелы-(цепь+:ЦЕПЬ);
(* Удаляет пробелы в начале и конце цепочки <цепь>. *)
УКАЗ
  УдалитьНачПробелы(цепь);
  УдалитьКонПробелы(цепь)
КОН УдалитьПробелы;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ВставитьЗнак-(зн:ЗНАК; куда+:ЦЕПЬ; кудап:ЦЕЛ);
(* Вставляет знак <зн> в цепочку <куда> в позиции <кудап>,
 * если для этого есть место. *)
ПЕР
  поз,кудадл:ЦЕЛ;
УКАЗ
  кудадл:=ДЛИНА(куда);
  ЕСЛИ кудадл+1 < РАЗМЕР(куда) ТО
    ЕСЛИ  кудап < 0 ТО
      кудап:=0
    АЕСЛИ кудап > кудадл ТО
      кудап:=кудадл
    КОН;
    поз:=кудадл+1;
    ПОКА поз > кудап ВЫП
      куда[поз]:=куда[поз-1];
      УМЕНЬШИТЬ(поз)
    КОН;
    куда[поз]:=зн
  КОН
КОН ВставитьЗнак;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Вставить-(откуда-,куда+:ЦЕПЬ; кудап:ЦЕЛ);
(* Вставляет цепочку <откуда> в цепочку <куда> в позиции <кудап>.
 * Копирует знаков не больше, чем умещается в <куда>. *)
ПЕР
  откудап,кудадл,откудадл:ЦЕЛ;
УКАЗ
  откудадл:=ДЛИНА(откуда);
  кудадл:=ДЛИНА(куда);
  ЕСЛИ кудадл+откудадл+1 > РАЗМЕР(куда) ТО
    откудадл:=РАЗМЕР(куда)-кудадл-1
  КОН;
  ЕСЛИ  кудап < 0 ТО
    кудап:=0
  АЕСЛИ кудап > кудадл ТО
    кудап:=кудадл
  КОН;
  откудап:=кудадл;
  ПОКА откудап >= кудап ВЫП
    куда[откудап+откудадл]:=куда[откудап];
    УМЕНЬШИТЬ(откудап)
  КОН;
  откудап:=0;
  ПОКА откудап < откудадл ВЫП
    куда[кудап+откудап]:=откуда[откудап];
    УВЕЛИЧИТЬ(откудап)
  КОН
КОН Вставить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьКонПробелы-(цепь+:ЦЕПЬ; дл:ЦЕЛ);
(* Увеличивает длину цепочки <цепь> до <дл> знаков, добавляя в конец пробелы.
 * Если <цепь> уже достаточной длины, то не производит никаких изменений. *)
ПЕР
  поз,р:ЦЕЛ;
УКАЗ
  р:=РАЗМЕР(цепь);
  ЕСЛИ дл+1 > р ТО
    дл:=р-1
  КОН;
  поз:=ДЛИНА(цепь);
  ЕСЛИ поз < дл ТО
    ПОКА поз < дл ВЫП
      цепь[поз]:=" ";
      УВЕЛИЧИТЬ(поз)
    КОН;
    цепь[дл]:=0X
  КОН
КОН ДобавитьКонПробелы;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ДобавитьНачПробелы-(цепь+:ЦЕПЬ; дл:ЦЕЛ);
(* Увеличивает длину цепочки <цепь> до <дл> знаков, добавляя в начало пробелы.
 * Если <цепь> уже достаточной длины, то не производит никаких изменений. *)
ПЕР
  поз,р:ЦЕЛ;
УКАЗ
  р:=РАЗМЕР(цепь);
  ЕСЛИ дл+1 > р ТО
    дл:=р-1
  КОН;
  поз:=ДЛИНА(цепь);
  ЕСЛИ поз < дл ТО
    ПОКА поз > 0 ВЫП
      цепь[дл]:=цепь[поз];
      УМЕНЬШИТЬ(дл); 
      УМЕНЬШИТЬ(поз)
    КОН;
    ПОКА дл > 0 ВЫП
      цепь[дл]:=" ";
      УМЕНЬШИТЬ(дл)
    КОН;
  КОН
КОН ДобавитьНачПробелы;

КОН Цепь.

 
 


Вопросы, замечания и предложения высылайте на atimopheyev@yahoo.com

 
Главная     ◄Глагол     ◄Азбука     ◄Задачи на Глаголе     Примеры приложений ►   Среда разработки ►   Отладка программ ►   Отличия от Оберона ►   Отличия от Паскаля ►   Ассемблер ARM ►   Глагол для ARM ►   ? и Ответы